package array

import (
	"errors"
	"fmt"
	"strings"
)

/*Array 动态数组*/

type Array[E any] struct {
	data []E
	size int
}

// MakeArray0 构造函数，传入数组的容量cap构造Array
func MakeArray0[E any](capacity int) *Array[E] {
	return &Array[E]{
		data: make([]E, capacity, capacity),
	}
}

// MakeArray 无参构造函数，默认数组的容量cap=10
func MakeArray[E any]() *Array[E] {
	return MakeArray0[E](10)
}

// GetSize 获取数组元素个数
func (arr *Array[E]) GetSize() int {
	return arr.size
}

// GetCap 获取数组元素容量
func (arr *Array[E]) GetCap() int {
	return cap(arr.data)
}

// IsEmpty 数组是否为空
func (arr *Array[E]) IsEmpty() bool {
	return arr.size == 0
}

// Get 获取index索引位置的元素
func (arr *Array[E]) Get(index int) (E, error) {
	var zero E
	if index < 0 || index >= arr.size {
		//这里有细节，不能直接返回nil，因为不确定E具体类型，E为Integer就是int类型，零值为0
		return zero, errors.New("get failed. Index is illegal")
	}
	return arr.data[index], nil
}

// GetLast 获取数组最后一个元素
func (arr *Array[E]) GetLast() (E, error) {
	return arr.Get(arr.size - 1)
}

// GetFirst 获取数组第一个元素
func (arr *Array[E]) GetFirst() (E, error) {
	return arr.Get(0)
}

// Set 修改index索引位置的元素为e
func (arr *Array[E]) Set(index int, e E) error {
	if index < 0 || index >= arr.size {
		return errors.New("get failed. Index is illegal")
	}
	arr.data[index] = e
	return nil
}

// AddLast 向所有元素后添加一个新元素
func (arr *Array[E]) AddLast(e E) error {
	return arr.Add(arr.size, e)
}

// AddFirst 向所有元素头添加一个新元素
func (arr *Array[E]) AddFirst(e E) error {
	return arr.Add(0, e)
}

// Add 在第index个位置插入一个新元素e
func (arr *Array[E]) Add(index int, e E) error {
	if index < 0 || index > arr.size {
		return errors.New("add failed. Require index >= 0 and index <= len")
	}
	if arr.size == arr.GetCap() {
		//1倍扩容
		arr.resize(2 * arr.GetCap())
	}
	for i := arr.size - 1; i >= index; i-- {
		arr.data[i+1] = arr.data[i]
	}
	arr.data[index] = e
	arr.size++
	return nil
}

// Remove 从数组中删除index位置的元素，返回删除的元素
func (arr *Array[E]) Remove(index int) (E, error) {
	var zero E
	if index < 0 || index >= arr.size {
		return zero, errors.New("remove failed. Index is illegal")
	}
	ret := arr.data[index]
	for i := index; i < arr.size-1; i++ {
		arr.data[i] = arr.data[i+1]
	}
	arr.size--
	arr.data[arr.size] = zero
	//1/4缩容一半,数组长度不能为0，否则无法扩容
	if arr.size == arr.GetCap()/4 && arr.GetCap()/2 != 0 {
		arr.resize(arr.GetCap() / 2)
	}
	return ret, nil
}

// RemoveFirst 从数组中删除第一个元素，返回删除的元素
func (arr *Array[E]) RemoveFirst() (E, error) {
	return arr.Remove(0)
}

// RemoveLast 从数组中删除最后一个元素，返回删除的元素
func (arr *Array[E]) RemoveLast() (E, error) {
	return arr.Remove(arr.size - 1)
}

func (arr *Array[E]) resize(capacity int) {
	newArr := make([]E, capacity, capacity)
	copy(newArr, arr.data)
	arr.data = newArr
}

func (arr *Array[E]) String() string {
	sb := strings.Builder{}
	sb.WriteString(fmt.Sprintf("Array: size = %d , cap = %d\n",
		arr.size, arr.GetCap()))
	sb.WriteString(fmt.Sprintf("%+v", arr.data[:arr.size]))
	return sb.String()
}
